package com.lhkj.ct.meta.modules.psychology.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhkj.ct.base.model.dto.PageQuery;
import com.lhkj.ct.base.mybatis.extension.service.impl.IServiceImpl;
import com.lhkj.ct.base.utils.MathUtil;
import com.lhkj.ct.base.utils.ShiroUtil;
import com.lhkj.ct.base.utils.Validate;
import com.lhkj.ct.base.utils.file.word.PoiWordUtils;
import com.lhkj.ct.meta.modules.psychology.mapper.GroupReportMapper;
import com.lhkj.ct.meta.modules.psychology.model.entity.TblScaleGroupRelation;
import com.lhkj.ct.meta.modules.psychology.model.entity.TblScaleGroupReport;
import com.lhkj.ct.meta.modules.psychology.model.entity.TblScaleReportContent;
import com.lhkj.ct.meta.modules.psychology.model.vo.DimDistribution;
import com.lhkj.ct.meta.modules.psychology.model.vo.DimenStatistics;
import com.lhkj.ct.meta.modules.psychology.model.vo.GroupReportVo;
import com.lhkj.ct.meta.modules.psychology.service.GroupReportRelationService;
import com.lhkj.ct.meta.modules.psychology.service.GroupReportService;
import com.lhkj.ct.meta.modules.report.BaseFactory;
import com.lhkj.ct.meta.modules.report.word.group.ExportGroupReport;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 团体报告表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2023-10-20
 */
@Service
public class GroupReportServiceImpl extends IServiceImpl<GroupReportMapper, TblScaleGroupReport> implements GroupReportService {

    @Resource
    private GroupReportRelationService reportRelationService;

    @Override
    public IPage<TblScaleGroupReport> selectPages(TblScaleGroupReport groupReport, PageQuery pageQuery) {
        return getBaseMapper().selectPages(generatePageDesc(pageQuery, TblScaleGroupReport::getCreateTime), groupReport, pageQuery);
    }

    @Override
    @Transactional
    public boolean save(TblScaleGroupReport groupReport) {
        groupReport.setCreateBy(ShiroUtil.getAuthUserInfo().getUserId());
        getBaseMapper().insert(groupReport);
        String gid = groupReport.getId();
        List<TblScaleGroupRelation> relations = groupReport.getReportIds().stream().map(rid -> new TblScaleGroupRelation(gid, rid)).collect(Collectors.toList());
        return reportRelationService.saveBatch(relations);
    }

    @Override
    public GroupReportVo selectGroupRepInfo(String gId) {
        GroupReportVo reportVo = getBaseMapper().selectReportInfo(gId);
        Validate.isFalse(null == reportVo , "团体报告不存在或已删除!");
        reportVo.setCounts(reportVo.getRIds().size());
        // 团队平均状态
        reportVo.setAvgList(selectAvgState(reportVo.getScaleId(), gId));
        // 人员分布
        List<DimDistribution> dist = getBaseMapper().distribution(reportVo.getScaleId(), reportVo.getId());
        // 处理百分比
        for (DimDistribution distribution : dist) {
            //处理人员分布百分比
            BigDecimal distValue = MathUtil.divide(distribution.getCounts(), reportVo.getCounts(), 4);
            distribution.setDistPercentValue(distValue.doubleValue());
            distribution.setDistPercent(new DecimalFormat("0.##%").format(distValue));
        }
        reportVo.setDistList(dist);
        return reportVo;
    }

    @Override
    public void exportWord(String gId) {
        GroupReportVo data = selectGroupRepInfo(gId);
        XWPFDocument document = BaseFactory.getReport(new ExportGroupReport(), data);
        PoiWordUtils.wordDownload(document, data.getReportName() + ".docx");
    }

    @Override
    public void exportPdf(String gId) {
        GroupReportVo data = selectGroupRepInfo(gId);
        XWPFDocument document = BaseFactory.getReport(new ExportGroupReport(), data);
        PoiWordUtils.wordToPdfDownload(document, data.getReportName() + ".pdf");
    }

    private List<DimenStatistics> selectAvgState(String scaleId, String groupRepId) {
        List<TblScaleReportContent> reportContents = getBaseMapper().selectAvg(scaleId,groupRepId);
        return reportContents.stream().collect(Collectors.groupingBy(TblScaleReportContent::getDimName, LinkedHashMap::new, Collectors.toList()))
                .entrySet().stream().map(m -> {
                    DimenStatistics dimenStatistics = new DimenStatistics();
                    double avg = m.getValue().stream().mapToDouble(p -> p.getRealScore().doubleValue()).average().orElseGet(() -> 0D);
                    List<Double> collect = m.getValue().stream().mapToDouble(p -> p.getRealScore().doubleValue()).boxed().collect(Collectors.toList());
                    dimenStatistics.setDimName(m.getKey())
                            .setAvg(MathUtil.getFloorNum(avg, 2))
                            .setStd(MathUtil.getStandardDeviation( collect))
                            .setMedian(MathUtil.getMedian( collect))
                            .setMax( collect.stream().max(Comparator.comparing(x -> x)).orElse(0D))
                            .setMin(collect.stream().min(Comparator.comparing(x -> x)).orElse(0D));
                    return dimenStatistics;
                }).collect(Collectors.toList());
    }

}
